/**
 * 文件上传 公用类
 * @author WangXinLei
 * @date 2014-11-13
 */
package com.chnbst.bstyun.controller;

import java.io.File;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Random;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.chnbst.bstyun.core.common.ReadProperties;
import com.chnbst.bstyun.core.common.ZipUtil;
import com.chnbst.bstyun.core.common.qrcode.QRCodeUtil;
import com.chnbst.bstyun.model.pojo.AdminUser;
import com.chnbst.bstyun.model.pojo.Attach;
import com.chnbst.bstyun.model.pojo.User;
import com.chnbst.bstyun.service.AttachService;

@Controller
@RequestMapping("/uploadFile")
public class FileUpload {
	
	@Autowired
	private AttachService attachService;
	@Autowired
	private ReadProperties read;
	
	@SuppressWarnings("rawtypes")
	@RequestMapping(value="/image",method = RequestMethod.POST)
	public void fileUpload(HttpServletRequest request, HttpServletResponse response) throws Exception{
		
		response.setContentType("text/html; charset=UTF-8");
		PrintWriter out = response.getWriter();
		String attachType = request.getParameter("attachType");
		
		//创建的文件夹
		String objectName = request.getParameter("objectName");
		
		//定义返回消息
		String message = null;
		HashMap<String, Object> msgMap = new HashMap<String, Object>();

		//文件保存目录路径
		String savePath = request.getSession().getServletContext().getRealPath("/") + "/";
		//文件保存目录URL
		String saveUrl  = request.getContextPath() + "/";
		
		//定义允许上传的文件扩展名
		HashMap<String, String> extMap = new HashMap<String, String>();
		extMap.put("upload", "gif,jpg,jpeg,png,bmp");
		extMap.put("flash", "swf,flv");
		extMap.put("media", "swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb");
		extMap.put("file", "doc,docx,xls,xlsx,ppt,htm,html,txt,zip,rar,gz,bz2,apk");
		
		//最大文件大小(此处最大为4M)
		long maxSize = 4 * 1024 * 1024;
		
		if(!ServletFileUpload.isMultipartContent(request)){
			message = "请选择文件。";
			msgMap.put("message", message);
			new ObjectMapper().writeValue(out, msgMap);
			out.close();
		}
		
		//检查目录
		File uploadDir = new File(savePath);
		if(!uploadDir.isDirectory()){
			message = "上传目录不存在。";
			msgMap.put("message", message);
			new ObjectMapper().writeValue(out, msgMap);
			out.close();
		}
		
//		检查目录写权限
		if(!uploadDir.canWrite()){
			message = "上传目录没有写权限。";
			msgMap.put("message", message);
			new ObjectMapper().writeValue(out, msgMap);
			out.close();
		}
		
		String dirName = request.getParameter("dir");
		if (dirName == null) {
			dirName = "upload";
		}
		if(!extMap.containsKey(dirName)){
			message = "目录名不正确。";
			msgMap.put("message", message);
			new ObjectMapper().writeValue(out, msgMap);
			out.close();
		}
		
		//创建文件夹
		savePath += dirName + "/" + objectName + "/";
		saveUrl += dirName + "/" + objectName + "/";
		File saveDirFile = new File(savePath);
		if (!saveDirFile.exists()) {
			saveDirFile.mkdirs();
		}
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
		String ymd = sdf.format(new Date());
		savePath += ymd + "/";
		saveUrl += ymd + "/";
		File dirFile = new File(savePath);
		if (!dirFile.exists()) {
			dirFile.mkdirs();
		}
		
		FileItemFactory factory = new DiskFileItemFactory();
		ServletFileUpload upload = new ServletFileUpload(factory);
		upload.setHeaderEncoding("UTF-8");
		List items = upload.parseRequest(request);
		Iterator itr = items.iterator();
		
		FileItem item = (FileItem) itr.next();
		String fileName = item.getName();
		long fileSize = item.getSize();
		if (!item.isFormField()) {
			//检查扩展名
			String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
			if(!Arrays.<String>asList(extMap.get(dirName).split(",")).contains(fileExt)){
				message = "上传文件扩展名是不允许的扩展名。\n只允许" + extMap.get(dirName) + "格式。";
				msgMap.put("message", message);
				new ObjectMapper().writeValue(out, msgMap);
				out.close();
			}
			
			//检查文件大小
			if(fileSize > maxSize){
				message = "上传文件大小超过限制。";
				msgMap.put("message", message);
				new ObjectMapper().writeValue(out, msgMap);
				out.close();
			}

			SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
			String newFileName = df.format(new Date()) + "_" + new Random().nextInt(1000) + "." + fileExt;
			try{
				File uploadedFile = new File(savePath, newFileName);
				item.write(uploadedFile);
			}catch(Exception e){
				message = "上传文件失败。";
				msgMap.put("message", message);
				new ObjectMapper().writeValue(out, msgMap);
				out.close();
			}

			message = "上传文件成功";
			msgMap.put("message", message);
			String path = saveUrl + newFileName;
			msgMap.put("fileName", newFileName);
			msgMap.put("path", path);
			
			Integer userId = null;
			
			if(Integer.valueOf(attachType) == 1){
				User userInfo = (User) request.getSession().getAttribute("userInfo");
				userId = userInfo.getUserId();
				
			}else if(Integer.valueOf(attachType) == 2){
				AdminUser adminUser = (AdminUser) request.getSession().getAttribute("adminUser");
				userId = adminUser.getAdminId();
			}
			
			Attach attach = new Attach();
			attach.setAttachName(newFileName);
			attach.setAttachPath(path);
			attach.setAttachType(Integer.valueOf(attachType));
			attach.setCreateTime(new Date());
			attach.setUserId(userId);
			
			boolean b = attachService.insertAttach(attach);
			if(b) {
				msgMap.put("attachId", attach.getAttachId());
			}
			
			new ObjectMapper().writeValue(out, msgMap);
			out.close();
		}
		
	}
	
	@SuppressWarnings("rawtypes")
	@RequestMapping(value="/file",method = RequestMethod.POST)
	public void uploadFile(HttpServletRequest request, HttpServletResponse response) throws Exception{
		
		response.setContentType("text/html; charset=UTF-8");
		PrintWriter out = response.getWriter();
		
		//创建的文件夹
		String objectType = request.getParameter("objectType");
		String objectName = request.getParameter("objectName");
		
		//定义返回消息
		String message = null;
		HashMap<String, Object> msgMap = new HashMap<String, Object>();
		
		//文件保存目录路径
		String savePath = request.getSession().getServletContext().getRealPath("/") + "/";
		//文件保存目录URL
		String saveUrl  = request.getContextPath() + "/";
		
		//定义允许上传的文件扩展名
		HashMap<String, String> extMap = new HashMap<String, String>();
		extMap.put("image", "gif,jpg,jpeg,png,bmp");
		extMap.put("flash", "swf,flv");
		extMap.put("media", "swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb");
		extMap.put("upload", "doc,docx,xls,xlsx,ppt,htm,html,txt,zip,rar,gz,bz2,apk,ipa,exe");
		
		//最大文件大小(此处最大为100M)
		long maxSize = 100 * 1024 * 1024;
		
		if(!ServletFileUpload.isMultipartContent(request)){
			message = "请选择文件。";
			msgMap.put("message", message);
			new ObjectMapper().writeValue(out, msgMap);
			out.close();
		}
		
		//检查目录
		File uploadDir = new File(savePath);
		if(!uploadDir.isDirectory()){
			message = "上传目录不存在。";
			msgMap.put("message", message);
			new ObjectMapper().writeValue(out, msgMap);
			out.close();
		}
		
		//检查目录写权限
		if(!uploadDir.canWrite()){
			message = "上传目录没有写权限。";
			msgMap.put("message", message);
			new ObjectMapper().writeValue(out, msgMap);
			out.close();
		}
		
		String dirName = request.getParameter("dir");
		if (dirName == null) {
			dirName = "upload";
		}
		if(!extMap.containsKey(dirName)){
			message = "目录名不正确。";
			msgMap.put("message", message);
			new ObjectMapper().writeValue(out, msgMap);
			out.close();
		}
		
		//创建文件夹
		savePath += dirName + "/" + objectType + "/" + objectName + "/";
		saveUrl += dirName + "/" + objectType + "/" + objectName + "/";
		File saveDirFile = new File(savePath);
		if (!saveDirFile.exists()) {
			saveDirFile.mkdirs();
		}
		File dirFile = new File(savePath);
		if (!dirFile.exists()) {
			dirFile.mkdirs();
		}
		
		FileItemFactory factory = new DiskFileItemFactory();
		ServletFileUpload upload = new ServletFileUpload(factory);
		upload.setHeaderEncoding("UTF-8");
		List items = upload.parseRequest(request);
		Iterator itr = items.iterator();
		
		FileItem item = (FileItem) itr.next();
		String fileName = item.getName();
		long fileSize = item.getSize();
		if (!item.isFormField()) {
			//检查扩展名
			String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
			if(!Arrays.<String>asList(extMap.get(dirName).split(",")).contains(fileExt)){
				message = "上传文件扩展名是不允许的扩展名。\n只允许" + extMap.get(dirName) + "格式。";
				msgMap.put("message", message);
				new ObjectMapper().writeValue(out, msgMap);
				out.close();
			}
			
			//检查文件大小
			if(fileSize > maxSize){
				message = "上传文件大小超过限制。";
				msgMap.put("message", message);
				new ObjectMapper().writeValue(out, msgMap);
				out.close();
			}
			
			String newFileName = objectName + "." + fileExt;
			try{
				File uploadedFile = new File(savePath, newFileName);
				item.write(uploadedFile);
				
				/*如果上传的文件是zip类型，解压该文件*/
				if("zip".equals(fileExt)) {
					ZipUtil.unZipFiles(savePath + newFileName, savePath);
				}
			}catch(Exception e){
				message = "上传文件失败。";
				msgMap.put("message", message);
				new ObjectMapper().writeValue(out, msgMap);
				out.close();
			}
			
			message = "上传文件成功";
			msgMap.put("message", message);
			String path = saveUrl + newFileName;
			msgMap.put("fileName", newFileName);
			msgMap.put("path", path);
			if(!"exe".equals(fileExt)) {
				if("上传文件成功".equals(message)) {
					String proPath = request.getSession().getServletContext().getRealPath("/");
					String rootPath = read.getBstyunUrl();
					String qrcodeUrl = path.substring(0, path.lastIndexOf(".")+1)+"jpg";
					String imgPath = proPath + qrcodeUrl;
					String logo = proPath + "/images/admin/bstyun.png";
					msgMap.put("qrcodeUrl", qrcodeUrl);
					msgMap.put("qrcodeSrc", qrcodeUrl+"?"+Math.random());
					
					String qrcodeContent = rootPath+"/app.html?product="+objectName;
					System.out.println("内容:"+qrcodeContent);
					System.out.println(QRCodeUtil.encode(qrcodeContent, logo, imgPath, true));
				}
			}
			new ObjectMapper().writeValue(out, msgMap);
			out.close();
		}
	}
	
}
